package com.yuanfeng.payment.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jfinal.weixin.sdk.encrypt.WXBizMsgCrypt;
import com.yuanfeng.commoms.config.YFConfig;
import com.yuanfeng.commoms.constant.RedisConstants;
import com.yuanfeng.commoms.dto.OpenComponentDTO;
import com.yuanfeng.commoms.exception.BizCodeEnume;
import com.yuanfeng.commoms.util.*;
import com.yuanfeng.commoms.vo.user.UserInfoVO;
import com.yuanfeng.payment.entity.PayAuthorizationAppletInformationEntity;
import com.yuanfeng.payment.mapper.PayAuthorizationAppletInformationMapper;
import com.yuanfeng.payment.service.PayAuthorizationAppletInformationService;
import com.yuanfeng.payment.vo.templateListEntityVO;
import org.apache.commons.io.IOUtils;
import org.dom4j.DocumentException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.util.*;

/**
 * @ClassName PayAuthorizationAppletInformationServiceImpl
 * @Description  授权小程序信息表
 * @Author cyp
 * @Date 2023-07-20 09:39:51
 * @Version 1.0
 **/
@Service
@RefreshScope
public class PayAuthorizationAppletInformationServiceImpl extends ServiceImpl<PayAuthorizationAppletInformationMapper, PayAuthorizationAppletInformationEntity>
        implements PayAuthorizationAppletInformationService {

    @Value("${firstLevel}")
    private String firstLevel;

    @Override
    public ResponseResult queryShopAppletConfigFeign(Map<String, Object> map) {
        Map<String,String> resultMap = this.baseMapper.queryShopAppletConfigFeign(map.get("shopId").toString());
        return ResponseResult.success(resultMap);
    }

    @Override
    public ResponseResult querysecret(Map<String, Object> map) {
        String token = String.valueOf(map.get("token"));

        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(token);
        if(userInfo!=null){
            Integer shopId = Integer.valueOf(userInfo.getShopId());

            HashMap<String, Object> result = new HashMap<>();
            PayAuthorizationAppletInformationEntity querysecret = this.baseMapper.selectOne(new LambdaQueryWrapper<PayAuthorizationAppletInformationEntity>()
                    .eq(PayAuthorizationAppletInformationEntity::getShopId,shopId));
            if (querysecret != null){
                result.put("authorizerAppid",querysecret.getAuthorizerAppid());
                result.put("secret",querysecret.getSecret());
                return ResponseResult.success(result);
            }
            return ResponseResult.fail(BizCodeEnume.NO_INFORMATION_OBTAINED);
        }
            return ResponseResult.fail(BizCodeEnume.TOKEN_IS_INVALID);

    }

    @Override
    public ResponseResult release(Map<String, Object> map) {
        String token = String.valueOf(map.get("token"));
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(token);
        if(userInfo!=null){
            Integer shopId = Integer.valueOf(userInfo.getShopId());
            //根据shopId查询小程序信息
            PayAuthorizationAppletInformationEntity entity = this.baseMapper.selectOne(new LambdaQueryWrapper<PayAuthorizationAppletInformationEntity>()
                                                            .eq(PayAuthorizationAppletInformationEntity::getShopId,shopId));
            //授权小程序appid
            String authorizerAppid = entity.getAuthorizerAppid();
            String authorizerAccessToken = RedisUtil.get(authorizerAppid);

            //过期重新获取
            if (authorizerAccessToken == null){
                updateauthorizeraccesstoken();
            }
            authorizerAccessToken = RedisUtil.get(authorizerAppid);

            System.out.println(authorizerAccessToken);

            String url = OpenComponentDTO.releaseUrl+"?access_token="+authorizerAccessToken;
            JSONObject jsonObject = new JSONObject();

            String data = HttpsUtil.sendPost(url, jsonObject.toString());
            JSONObject getData = JSONObject.parseObject(data);
            if (getData.get("errcode").equals(0)){
                return ResponseResult.success(getData);
            }else{
                return ResponseResult.fail((Integer) getData.get("errcode"), (String) getData.get("errmsg"));
            }

        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_INVALID);
    }

    @Override
    public ResponseResult setPrivacySetting(Map<String, Object> map) {
        String token = String.valueOf(map.get("token"));
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(token);
        if(userInfo!=null) {
            Integer shopId = Integer.valueOf(userInfo.getShopId());
            //根据shopId查询小程序信息
            PayAuthorizationAppletInformationEntity entity = this.baseMapper.selectOne(new LambdaQueryWrapper<PayAuthorizationAppletInformationEntity>()
                    .eq(PayAuthorizationAppletInformationEntity::getShopId,shopId));
            //授权小程序appid
            String authorizerAppid = entity.getAuthorizerAppid();
            String authorizerAccessToken = RedisUtil.get(authorizerAppid);

            //过期重新获取
            if (StringUtils.isEmpty(authorizerAccessToken) || "null".equals(authorizerAccessToken)) {
                updateauthorizeraccesstoken();
            }
            authorizerAccessToken = RedisUtil.get(authorizerAppid);

            System.out.println(authorizerAccessToken);

            String url = OpenComponentDTO.setPrivacySettingUrl + "?access_token=" + authorizerAccessToken;

            //要收集的用户信息配置
            ArrayList<Object> setting_list = new ArrayList<>();
            JSONObject jsonObject1 = new JSONObject();
            jsonObject1.put("privacy_key", "Location");
            jsonObject1.put("privacy_text", "查询当前用户附近的门店信息");
            setting_list.add(jsonObject1);

            JSONObject jsonObject2 = new JSONObject();
            jsonObject2.put("privacy_key", "PhoneNumber");
            jsonObject2.put("privacy_text", "登录小程序");
            setting_list.add(jsonObject2);

            //通知方式
            JSONObject owner_setting = new JSONObject();
            owner_setting.put("notice_method", "短信");
            owner_setting.put("contact_phone", "15236038307");

            //小程序中引用了第三方sdk的信息说明
            ArrayList<Object> sdk_privacy_info_list = new ArrayList<>();
            JSONObject jsonObject3 = new JSONObject();
            jsonObject3.put("sdk_name", "wxParser");
            jsonObject3.put("sdk_biz_name", "广州爱范儿科技股份有限公司");


            ArrayList<Object> sdk_list = new ArrayList<>();
            JSONObject jsonObject4 = new JSONObject();
            jsonObject4.put("privacy_key", "");
            jsonObject4.put("privacy_text", "");
            sdk_list.add(jsonObject4);

            jsonObject3.put("sdk_list", sdk_list);

            //参数封装
            JSONObject jsonObject = new JSONObject();
            //1 表示现网版  2  表示开发版
            jsonObject.put("privacy_ver", 2);
            jsonObject.put("setting_list", setting_list);
            jsonObject.put("owner_setting", owner_setting);
            //jsonObject.put("sdk_privacy_info_list",sdk_privacy_info_list);

            String data = HttpsUtil.sendPost(url, jsonObject.toString());
            JSONObject getData = JSONObject.parseObject(data);
            if (getData.get("errcode").equals(0)){
                return ResponseResult.success(getData);
            }else{
                return ResponseResult.fail((Integer) getData.get("errcode"), (String) getData.get("errmsg"));
            }

        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_INVALID);
    }

    @Override
    public ResponseResult updatesecret(Map<String, Object> map) {
        String token = String.valueOf(map.get("token"));
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(token);
        if(userInfo!=null) {
        Integer shopId = Integer.valueOf(userInfo.getShopId());
        map.put("shopId",shopId);
        Integer updatesecret = this.baseMapper.updatesecret(map);
        if (updatesecret > 0){
            return ResponseResult.success(BizCodeEnume.UPDATE_SUCCEEDED);
        }
        return ResponseResult.fail(BizCodeEnume.UPDATE_ERROR);
        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_INVALID);
    }

    @Override
    public ResponseResult getLatestAuditStatus(Map<String, Object> map) {
        String token = String.valueOf(map.get("token"));
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(token);
        if(userInfo!=null) {
        Integer shopId = Integer.valueOf(userInfo.getShopId());
        //根据shopId查询小程序信息
        PayAuthorizationAppletInformationEntity entity = this.baseMapper.selectOne(new LambdaQueryWrapper<PayAuthorizationAppletInformationEntity>()
                                                        .eq(PayAuthorizationAppletInformationEntity::getShopId,shopId));
        //授权小程序appid
        String authorizerAppid = entity.getAuthorizerAppid();
        String authorizerAccessToken = RedisUtil.get(authorizerAppid);

        //过期重新获取
        if (authorizerAccessToken == null){
            updateauthorizeraccesstoken();
        }
        authorizerAccessToken = RedisUtil.get(authorizerAppid);

        System.out.println(authorizerAccessToken);

        String url = OpenComponentDTO.getLatestAuditStatusUrl+"?access_token="+authorizerAccessToken;

        String data = HttpsUtil.sendGet(url, "");
        JSONObject getData = JSONObject.parseObject(data);
        if (getData.get("errcode").equals(0)){
            return ResponseResult.success(getData);
        }

        return ResponseResult.fail(getData);
        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_INVALID);
    }

    @Override
    public ResponseResult submitAuditUrl(Map<String, Object> map) {
        String token = String.valueOf(map.get("token"));
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(token);
        if(userInfo!=null) {
        Integer shopId = Integer.valueOf(userInfo.getShopId());
        //根据shopId查询小程序信息
        PayAuthorizationAppletInformationEntity entity = this.baseMapper.selectOne(new LambdaQueryWrapper<PayAuthorizationAppletInformationEntity>()
                    .eq(PayAuthorizationAppletInformationEntity::getShopId,shopId));
        //授权小程序appid
        String authorizerAppid = entity.getAuthorizerAppid();
        String authorizerAccessToken = RedisUtil.get(authorizerAppid);

        //过期重新获取
        if (authorizerAccessToken == null){
            updateauthorizeraccesstoken();
        }
        authorizerAccessToken = RedisUtil.get(authorizerAppid);

        //获取接口隐藏信息检测结果
        String infoUrl = OpenComponentDTO.privacyUrl+"?access_token="+authorizerAccessToken;
        String info = HttpsUtil.sendGet(infoUrl, "");
        JSONObject jsonObject2 = JSONObject.parseObject(info);
        if (!jsonObject2.get("errcode").equals(0)){
            return ResponseResult.fail(jsonObject2);
        }

        //提交审核参数封装
        JSONObject jsonObject = new JSONObject();

        //获取类目信息
        String getAllCategoryNameUrl = OpenComponentDTO.getAllCategoryNameUrl+"?access_token="+authorizerAccessToken;
        String data = HttpsUtil.sendGet(getAllCategoryNameUrl, "");
        JSONObject getData = JSONObject.parseObject(data);
        if (getData.get("errcode").equals(0)){
            jsonObject.put("item_list",getData.get("category_list"));

        }else{
            return ResponseResult.fail(0, "获取类目名称异常");
        }

        String url = OpenComponentDTO.submitAuditUrl+"?access_token="+authorizerAccessToken;

        String data1 = HttpsUtil.sendPost(url, jsonObject.toString());
        JSONObject fromObject = JSONObject.parseObject(data1);
        if (fromObject.get("errcode").equals(0)){
            //将审核编号入库
           this.baseMapper.update(null,new LambdaUpdateWrapper<PayAuthorizationAppletInformationEntity>()
                            .eq(PayAuthorizationAppletInformationEntity::getAuthorizerAppid,authorizerAppid)
                            .set(PayAuthorizationAppletInformationEntity::getAuditId,String.valueOf(fromObject.get("auditid"))));
            return ResponseResult.success(fromObject);
        }
        return ResponseResult.fail(fromObject);
        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_INVALID);
    }

    @Override
    public ResponseResult uploadMediaToCodeAudit(MultipartFile mediaFile, String token) {
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(token);
        if(userInfo!=null) {
        Integer shopId = Integer.valueOf(userInfo.getShopId());
         //根据shopId查询小程序信息
         PayAuthorizationAppletInformationEntity entity = this.baseMapper.selectOne(new LambdaQueryWrapper<PayAuthorizationAppletInformationEntity>()
                 .eq(PayAuthorizationAppletInformationEntity::getShopId,shopId));
         //授权小程序appid
         String authorizerAppid = entity.getAuthorizerAppid();
        String authorizerAccessToken = RedisUtil.get(authorizerAppid);

        //过期重新获取
        if (authorizerAccessToken == null){
            updateauthorizeraccesstoken();
        }
        authorizerAccessToken = RedisUtil.get(authorizerAppid);

        try {
            URL urlObj = new URL(OpenComponentDTO.uploadmediaUrl+"?access_token=" + authorizerAccessToken);
            HttpURLConnection conn = (HttpURLConnection)urlObj.openConnection();
            conn.setRequestMethod("POST");
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Charset", "UTF-8");
            String BOUNDARY = "----------" + System.currentTimeMillis();
            conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY);
            StringBuilder sb = new StringBuilder();
            sb.append("--");
            sb.append(BOUNDARY);
            sb.append("\r\n");
            sb.append("Content-Disposition:form-data;name=\"media\";filename=\"" + mediaFile.getOriginalFilename() + "\";filelength=\"" + mediaFile.getSize() + "\"\r\n");
            sb.append("Content-Type:application/octet-stream\r\n\r\n");
            byte[] head = sb.toString().getBytes("utf-8");
            OutputStream out = new DataOutputStream(conn.getOutputStream());
            out.write(head);
            out.write(mediaFile.getBytes());
            byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");
            out.write(foot);
            out.flush();
            out.close();
            StringBuffer buffer = new StringBuffer();
            BufferedReader reader = null;
            String result = null;

            try {
                reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String line = null;

                while((line = reader.readLine()) != null) {
                    buffer.append(line);
                }

                if (result == null) {
                    result = buffer.toString();
                }
            } catch (IOException var17) {
                var17.printStackTrace();
            } finally {
                reader.close();
            }

            JSONObject getData = JSONObject.parseObject(result);
            if (getData.get("errcode").equals(0)){
                System.out.println(getData.get("type"));
                if (getData.get("type").equals("image")){
                    this.baseMapper.update(null,new LambdaUpdateWrapper<PayAuthorizationAppletInformationEntity>()
                            .eq(PayAuthorizationAppletInformationEntity::getAuthorizerAppid,authorizerAppid)
                            .set(PayAuthorizationAppletInformationEntity::getPicIdList,String.valueOf(getData.get("mediaid"))));
                }else{
                    this.baseMapper.update(null,new LambdaUpdateWrapper<PayAuthorizationAppletInformationEntity>()
                            .eq(PayAuthorizationAppletInformationEntity::getAuthorizerAppid,authorizerAppid)
                            .set(PayAuthorizationAppletInformationEntity::getVideoIdList,String.valueOf(getData.get("mediaid"))));
                }
                return ResponseResult.success(getData.get("mediaid"));
            }
        } catch (IOException var19) {

            return ResponseResult.fail(BizCodeEnume.OPERATION_FAILED);
        }
            return ResponseResult.fail(BizCodeEnume.OPERATION_FAILED);
        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_INVALID);
    }

    @Override
    public ResponseResult getqrcode(Map<String, Object> map) {
        String token = String.valueOf(map.get("token"));
        String encoded = null;
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(token);
        if(userInfo!=null) {
            Integer shopId = Integer.valueOf(userInfo.getShopId());
        //根据shopId查询小程序信息
        PayAuthorizationAppletInformationEntity entity = this.baseMapper.selectOne(new LambdaQueryWrapper<PayAuthorizationAppletInformationEntity>()
                .eq(PayAuthorizationAppletInformationEntity::getShopId,shopId));
        //授权小程序appid
        String authorizerAppid = entity.getAuthorizerAppid();
        String authorizerAccessToken = RedisUtil.get(authorizerAppid);

        //过期重新获取
        if (authorizerAccessToken == null){
            updateauthorizeraccesstoken();
        }
        authorizerAccessToken = RedisUtil.get(authorizerAppid);


        String url = OpenComponentDTO.getqrcodeUrl+"?access_token="+authorizerAccessToken;

        String path = "store%2FstoreIndex%2FstoreIndex%3FshopId%3D"+shopId;

        URI u = URI.create(url+"&path="+path);

        try (InputStream inputStream = u.toURL().openStream()) {
//           copyInputStreamToFile(inputStream);

            byte[] bytes = new byte[0];
            bytes = IOUtils.toByteArray(inputStream);
            encoded = Base64.getEncoder().encodeToString(bytes);

        }catch (IOException e) {
            e.printStackTrace();
        }
        return ResponseResult.success("data:image/jpeg;base64," + encoded);
        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_INVALID);

    }

    @Override
    public ResponseResult commit(Map<String, Object> map) {
        String token = String.valueOf(map.get("token"));
        String encoded = null;
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(token);
        if(userInfo!=null) {
            Integer shopId = Integer.valueOf(userInfo.getShopId());
            //根据shopId查询小程序信息
            PayAuthorizationAppletInformationEntity entity = this.baseMapper.selectOne(new LambdaQueryWrapper<PayAuthorizationAppletInformationEntity>()
                    .eq(PayAuthorizationAppletInformationEntity::getShopId,shopId));
            //授权小程序appid
            String authorizerAppid = entity.getAuthorizerAppid();
            String authorizerAccessToken = RedisUtil.get(authorizerAppid);

            //过期重新获取
            if (authorizerAccessToken == null){
                updateauthorizeraccesstoken();
            }
            authorizerAccessToken = RedisUtil.get(authorizerAppid);

            String url = OpenComponentDTO.commitUrl+"?access_token="+authorizerAccessToken;
            JSONObject jsonObject = new JSONObject();

            JSONObject jsonObject1 =new JSONObject();
            jsonObject1.put("shopId",shopId);
            JSONObject jsonObject2 =new JSONObject();

            jsonObject2.put("ext", jsonObject1.toString());
            jsonObject2.put("extAppid",authorizerAppid);
            jsonObject2.put("extEnable",true);

            //插件配置
            JSONObject jsonObject3 = new JSONObject();

            //直播插件
            JSONObject jsonObject4 = new JSONObject();
    //        jsonObject4.put("provider","wx2b03c6e691cd7370");
    //        jsonObject4.put("version","1.3.0");
    //        jsonObject3.put("live-player-plugin",jsonObject4);
            JSONObject jsonObject5 = new JSONObject();
            jsonObject4.put("provider","wx9d4d4ffa781ff3ac");
            jsonObject4.put("version","0.4.0");
            jsonObject3.put("my-plugin",jsonObject5);

            jsonObject2.put("plugins",jsonObject3);

            jsonObject.put("template_id", map.get("templateId"));
            jsonObject.put("ext_json", jsonObject2.toString());

            System.out.println("jsonObject==="+jsonObject);
            String data = HttpsUtil.sendPost(url, jsonObject.toString());
            System.out.println("data==="+data);
            JSONObject getData = JSONObject.parseObject(data);
            if (getData.get("errcode").equals(0)){
                return ResponseResult.success(getData);
            }else{
                return ResponseResult.fail((Integer) getData.get("errcode"), (String) getData.get("errmsg"));
            }
        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_INVALID);

    }

    @Override
    public ResponseResult addToTemplate(Map<String, Object> map) {
        String token = String.valueOf(map.get("token"));
        String userInfoStr = RedisUtil.get(YFConfig.YF_USER_TOKEN_USER + token);
        if (null == userInfoStr || userInfoStr.equals("")) {
            return ResponseResult.fail(BizCodeEnume.TOKEN_IS_INVALID);
        }
        boolean isExist = RedisUtil.exists("component_access_token");
        //第三方平台接口调用凭证
        String component_access_token = RedisUtil.get("component_access_token");
        System.out.println(component_access_token);

        if(!isExist){
            component_access_token = getComponentAccessToken(false);
        }
        String url = OpenComponentDTO.gettemplatelistUrl+"?access_token="+component_access_token;
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("template_type", 0);
        String data = HttpsUtil.sendGet(url, jsonObject.toString());

        JSONObject getData = JSONObject.parseObject(data);

        List<templateListEntityVO> templateList = JSON.parseObject( getData.get("template_list").toString(), new TypeReference<List<templateListEntityVO>>() {
        });

        Optional<templateListEntityVO> max = templateList.stream().
                max(Comparator.comparingLong(templateListEntityVO::getTemplateId));

        System.out.println();

        if (getData.get("errcode").equals(0)){
            return ResponseResult.success(max.get());
        }
        return ResponseResult.fail();
    }

    @Override
    public ResponseResult getPreauthCode(Map<String, Object> map) {
        String token = String.valueOf(map.get("token"));
        String userInfoStr = RedisUtil.get(YFConfig.YF_USER_TOKEN_USER + token);
        if (null == userInfoStr || userInfoStr.equals("")) {
            return ResponseResult.fail(BizCodeEnume.TOKEN_IS_INVALID);
        }
        //判断缓存中是否存在
        boolean isExist = RedisUtil.exists("component_access_token");
        String componentAccessToken = RedisUtil.get("component_access_token");
        /**token若不存在，返回重新获取*/
        if(!isExist){
            componentAccessToken = getComponentAccessToken(false);
        }
        /**拼装待发送的Json*/
        String url = OpenComponentDTO.pre_auth_code_url+"?component_access_token="+componentAccessToken;
        JSONObject json = new JSONObject();
        json.put("component_appid",OpenComponentDTO.appId);

        /**发送Https请求到微信*/
        String retStr = HttpsUtil.sendPost(url,json.toString());
        JSONObject resultJson = JSONObject.parseObject(retStr);
        if(resultJson == null ||
                (resultJson.getString("errcode") != null && resultJson.getString("errcode").equals("42001"))){
            componentAccessToken = getComponentAccessToken(true);
            /**拼装待发送的Json*/
            url = OpenComponentDTO.pre_auth_code_url+"?component_access_token="+componentAccessToken;

            /**发送Https请求到微信*/
            retStr = HttpsUtil.sendPost(url,json.toString());
            resultJson = JSONObject.parseObject(retStr);
        }
        String preauthcode = resultJson.getString("pre_auth_code");
        if (preauthcode == null){
            return ResponseResult.fail();
        }

        RedisUtil.set("pre_auth_code", preauthcode, 1800);

        //生成授权码   回调路径上线后改成页面路径
        String returnUrl = OpenComponentDTO.componentloginpageUrl + "?component_appid="+OpenComponentDTO.appId+
                "&pre_auth_code="+preauthcode+"&redirect_uri="+ firstLevel + "/mall-payment/pay/authorizationAppletInformation/authcode?token="+token;

        return ResponseResult.success(returnUrl);
    }

    @Override
    public ResponseResult checkAuth(Map<String, Object> map) {
        String token = String.valueOf(map.get("token"));
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(token);
        if(userInfo!=null) {
        Integer shopId = Integer.valueOf(userInfo.getShopId());
        //根据shopId查询小程序
        int count =this.baseMapper.selectCount(new LambdaQueryWrapper<PayAuthorizationAppletInformationEntity>()
                    .eq(PayAuthorizationAppletInformationEntity::getShopId,shopId));
          if (count > 0){
              return ResponseResult.success(BizCodeEnume.MERCHANT_HAS_AUTHORIZED_THE_MINI_PROGRAM);
          }
          return ResponseResult.fail(BizCodeEnume.MERCHANT_IS_NOT_AUTHORIZED_FOR_THE_MINI_PROGRAM);
        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_INVALID);
    }

    @Override
    public String ticket(String timestamp, String nonce, String msgSignature, String postData) {

        System.out.println("++++++++++++++++++"+timestamp+"----"+nonce+"----"+msgSignature+"----"+postData);

        try {
            //这个类是微信官网提供的解密类,需要用到消息校验Token 消息加密Key和服务平台appid
            WXBizMsgCrypt pc = new WXBizMsgCrypt(OpenComponentDTO.COMPONENT_TOKEN,
                    OpenComponentDTO.aesKey, OpenComponentDTO.appId);
            String xml = pc.decryptMsg(msgSignature, timestamp, nonce, postData);
            Map<String, Object> result = null;// 将xml转为map
            try {
                result = Xml2MapUtil.xml2map(xml);
            } catch (DocumentException e) {
                e.printStackTrace();
            }
            Map<String, Object> xml1 = (Map<String, Object>) result.get("xml");
            String componentVerifyTicket = String.valueOf(xml1.get("ComponentVerifyTicket"));

            // 存储平台授权票据,保存ticket
            OpenComponentDTO.component_verify_ticket = componentVerifyTicket;
            RedisUtil.set("componentVerifyTicket", componentVerifyTicket, 7000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "success";
    }

    @Override
    public void authcode(HttpServletResponse response, String authCode, String expiresIn, String token){
        String userInfoStr = RedisUtil.get(RedisConstants.FKGOU_USER_TOKEN_USER + token);
        if (null == userInfoStr || userInfoStr.equals("")) {
            //return "token无效";
        }
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(token);
        Integer shopId = Integer.valueOf(userInfo.getShopId());
        //清除缓存中的预授权码
        RedisUtil.remove("pre_auth_code");
        boolean isExist = RedisUtil.exists("component_access_token");
        String component_access_token = RedisUtil.get("component_access_token");
        if(!isExist){
            component_access_token = getComponentAccessToken(false);
        }

        try {

            //设置请求参数
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("component_appid", OpenComponentDTO.appId);
            jsonObject.put("authorization_code", authCode);
            String api_query_auth = OpenComponentDTO.OPEN_URL_AUTHORIZERACCESSTOKEN+"?component_access_token="+component_access_token;
            String responseData = HttpsUtil.sendPost(api_query_auth,jsonObject.toString());
            JSONObject postData = JSONObject.parseObject(responseData);

            JSONObject authorizationInfo = (JSONObject) postData.get("authorization_info");   //得到授权信息
            String authorizerAppid = (String) authorizationInfo.get("authorizer_appid");   //得到授权方 APPID    （存入数据库）
            String authorizerAccessToken = (String) authorizationInfo.get("authorizer_access_token");   //得到接口调用令牌
            String authorizerRefreshToken = (String) authorizationInfo.get("authorizer_refresh_token");   //得到接口刷新令牌   （存入数据库）
            Integer accessTokenexpiresIn = (Integer) authorizationInfo.get("expires_in");   //接口调用令牌的有效期

            //先数据库插入授权信息
            PayAuthorizationAppletInformationEntity infoEntity = new PayAuthorizationAppletInformationEntity();
            infoEntity.setAuthorizerAppid(authorizerAppid);
            infoEntity.setAuthorizerRefreshToken(authorizerRefreshToken);
            infoEntity.setShopId(shopId);

            //根据authorizerAppid查询小程序信息
            PayAuthorizationAppletInformationEntity authorizationInfoEntity = this.baseMapper.selectOne(new LambdaQueryWrapper<PayAuthorizationAppletInformationEntity>()
                    .eq(PayAuthorizationAppletInformationEntity::getAuthorizerAppid,authorizerAppid));
            Integer integer = null;
            if (authorizationInfoEntity == null){
                integer = this.baseMapper.insert(infoEntity);
            }else{
                integer = this.baseMapper.update(infoEntity,new LambdaUpdateWrapper<PayAuthorizationAppletInformationEntity>()
                        .eq(PayAuthorizationAppletInformationEntity::getAuthorizerAppid,authorizerAppid));
            }

            if (integer <= 0){
                //return "fail";
            }

            //将token存入redis
            RedisUtil.set(authorizerAppid,authorizerAccessToken,7000);

        } catch (Exception e) {

        }
        try {
            //扫码成功后跳转到 success.html页面 或者给予提示信息
            response.sendRedirect(firstLevel + "/bcenter/#/shop/appletmanagement");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void updateauthorizeraccesstoken(){
        List<PayAuthorizationAppletInformationEntity> updaterefreshtoken = new ArrayList<>();
        boolean isExist = RedisUtil.exists("component_access_token");
        //第三方平台接口调用凭证
        String component_access_token = RedisUtil.get("component_access_token");
        if(!isExist){
            component_access_token = getComponentAccessToken(false);
        }
        //获取授权帐号调用令牌
        String url = OpenComponentDTO.authorizer_access_token_url+"?component_access_token=" + component_access_token;
        List<PayAuthorizationAppletInformationEntity> list = this.baseMapper.selectList(new LambdaQueryWrapper<PayAuthorizationAppletInformationEntity>());
        if (list.size() > 0 && list != null) {
            for (PayAuthorizationAppletInformationEntity authorizerInfo : list) {

                String data;
                try {
                    //设置请求参数
                    JSONObject jsonObject = new JSONObject();
                    if (authorizerInfo != null) {
                        //第三方平台appid
                        jsonObject.put("component_appid", OpenComponentDTO.appId);
                        //授权方appid
                        jsonObject.put("authorizer_appid", authorizerInfo.getAuthorizerAppid());
                        //授权方刷新token
                        jsonObject.put("authorizer_refresh_token", authorizerInfo.getAuthorizerRefreshToken());

                        data = HttpsUtil.sendPost(url, jsonObject.toString());
                        JSONObject postData = JSONObject.parseObject(data);

                        String authorizer_access_token = String.valueOf((postData.get("authorizer_access_token")));
                        String authorizer_refresh_token = String.valueOf((postData.get("authorizer_refresh_token")));

                        //将token存入redis
                        RedisUtil.set(authorizerInfo.getAuthorizerAppid(),authorizer_access_token,7000);

                        if (authorizer_access_token != null && authorizer_refresh_token != null) {
                            authorizerInfo.setAuthorizerRefreshToken(authorizer_refresh_token);
                            updaterefreshtoken.add(authorizerInfo);
                        }
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        for (PayAuthorizationAppletInformationEntity entity : updaterefreshtoken)
        {
            //批量更新刷新token
            this.baseMapper.updateById(entity);
        }

    }

    /**
     * 获取component_access_token
     * @return
     */
    public String getComponentAccessToken(boolean flag) {
        //判断缓存中是否存在
        boolean isExist = RedisUtil.exists("componentVerifyTicket");
        String componentAccessToken = null;
        /**ticket若不存在，返回错误信息*/
        if(!isExist || flag){
            /**错误信息*/
            String url = "https://api.weixin.qq.com/cgi-bin/stable_token";
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("grant_type", "client_credential");
            jsonObject.put("appid", OpenComponentDTO.appId);
            jsonObject.put("secret", OpenComponentDTO.secret);
            String data = HttpsUtil.sendPost(url, jsonObject.toString());

            JSONObject resultJson = JSONObject.parseObject(data);
            componentAccessToken = resultJson.getString("access_token");
//            return "如果出现这条消息，说明ticket以及token的过期处理存在BUG";
            /**保存token，并设置有效时间*/
            RedisUtil.set("component_access_token", componentAccessToken, 7000);
            return componentAccessToken;
        }
        String componentVerifyTicket = RedisUtil.get("componentVerifyTicket");
        /**拼装待发送的Json*/
        JSONObject json = new JSONObject();
        json.put("component_appid", OpenComponentDTO.appId);
        json.put("component_appsecret",OpenComponentDTO.secret);
        json.put("component_verify_ticket",componentVerifyTicket);

        /**发送Https请求到微信*/
        String retStr = HttpsUtil.sendPost(OpenComponentDTO.component_access_token_url,json.toString());
        System.out.println(retStr);

        JSONObject resultJson = JSONObject.parseObject(retStr);
        /**在返回结果中获取token*/
        componentAccessToken = resultJson.getString("component_access_token");
        /**保存token，并设置有效时间*/
        RedisUtil.set("component_access_token", componentAccessToken, 7000);
        return componentAccessToken;
    }

}
